const MongoClient = require('mongodb').MongoClient;
let bson=require('bson');
let collection = {};
let DB_CONN_STR = 'mongodb://localhost:27017';
const dbName = 'finance';
MongoClient.connect(DB_CONN_STR, function (err, client) {
    if (err) throw  err;
    collection = client.db(dbName).collection('finance');
});

function getTodayStr() {
    let date = new Date();
    let seperator1 = "-";
    let month = date.getMonth() + 1;
    let strDate = date.getDate();
    if (month >= 1 && month <= 9) {
        month = "0" + month;
    }
    if (strDate >= 0 && strDate <= 9) {
        strDate = "0" + strDate;
    }
    return date.getFullYear() + seperator1 + month + seperator1 + strDate;
}

function create(data, callback) {
    let arr = [];
    for (let detail of data.finance) {
        let doc = {
            year: data.date.substr(0, 4),
            month: data.date.substr(5, 2),
            day: data.date.substr(8, 2),
            time: data.date
        };
        doc.content = detail.detail;
        doc.amount = parseFloat(detail.amount) * 100;

        arr.push(doc);
    }
    collection.insertMany(arr, function (err, result) {
        if (err) throw err;
        callback()
    });
}

function deleteRecord(arg, callback) {
    collection.deleteOne({_id: bson.ObjectId(arg.id)}, (err, result) => {
        if (err) {
            throw  err;
        }

        getToday(callback);
    })
}

function getToday(callback) {
    let date = getTodayStr();
    collection.find({time: date}).toArray(function (err, result) {
        if (err) throw  err;
        callback(result);
    })
}

function getMonth(callback) {
    let date = new Date();
    let year = date.getFullYear();
    let month = date.getMonth() + 1;
    month = month > 10 ? month : '0' + month;
    collection.find({year: year.toString(), month: month})
        .sort({time: 1})
        .toArray((err, result) => {
            if (err) throw  err;

            callback(formatMonth(result));
        })
}

function formatMonth(result) {
    let month = {};

    result.forEach((row) => {
        if (!(row.time in month)) {
            month[row.time] = [];
        }
        month[row.time].push(row);
    });

    result = [];
    let all = 0;
    for (let m in month) {
        let list = [], total = 0, doc = {};
        list = month[m];
        list.forEach((row) => {
            total += row.amount;
        });
        doc.total = total;
        doc.list = list;
        doc.date = m.substr(0, 4) + '年' + m.substr(5, 2) + '月' + m.substr(8, 2) + '日';
        all += total;
        result.push(doc)
    }
    return {all: all, list: result}
}

function getYear(args, callback) {
    collection.find({year: args.year.toString(), month: args.month.toString()}).toArray((err, result) => {
        if (err) throw  err;

        collection.distinct('year', {}, {}, (err, years) => {

            result = formatMonth(result);

            let data = {
                year: args.year,
                month: args.month,
                list: result.list,
                all: result.all,
                years: years
            };

            callback(data);
        });
    })

}

function getAll(callback) {
    collection.aggregate(
        [
            {$group: {'_id': {year: '$year', month: '$month'}, amount: {$sum: '$amount'}}},
        ],
        {},
        (err, result) => {

            result.toArray((err, data) => {
                let years = {}, total = 0;
                data.forEach((row) => {
                    if (!(row._id.year in years)) {
                        years[row._id.year] = [];
                    }
                    years[row._id.year].push({month: row._id.month, amount: row.amount});
                    total += row.amount;
                });

                result = [];
                for (let year in years) {
                    let list = years[year], total = 0;
                    list.sort((a, b) => {
                        return a.month - b.month
                    });
                    list.forEach((row) => {
                        total += row.amount;
                    });
                    result.push({year: year, total: total, list: list})
                }

                result.sort((a, b) => {
                    return b.year - a.year
                });

                callback({total: total, list: result});

            });
        });
}


let finance = {};
finance.create = create;
finance.deleteRecord = deleteRecord;
finance.getToday = getToday;
finance.getMonth = getMonth;
finance.getYear = getYear;
finance.getAll = getAll;

module.exports = finance;